package net.zz.base.validate;


import net.zz.base.exception.CommonException;
import net.zz.base.validate.constraintvalidators.Validate;
import net.zz.base.validate.plug.CustomVali;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;


/**
 * Created by ZaoSheng on 2015/5/9.
 */
@Component
@Aspect
public class ZZValidate {
    @Resource
    private Validate validate;

    @Before(value = "execution(@javax.validation.Valid public * *(..))")
    public void validate(JoinPoint joinPoint) throws Exception {

        Signature sign = joinPoint.getSignature();
        Object[] objects = joinPoint.getArgs();
        Object target = joinPoint.getTarget();

        MethodSignature msign = (MethodSignature) sign;
        Method method = msign.getMethod();
        Annotation[][] parameterAnns = method.getParameterAnnotations();
        int arg = -1; //用于存放点前第几个参数

        //JDK8的新特性，参数类
//        Parameter[] parameters = method.getParameters();
        //JDK8的新特性，参数类
//        for (Parameter parameter : parameters) {

        for (Annotation[] annotations : parameterAnns) {
            arg++;

//            Annotation[] annotations = parameter.getAnnotations();
            if(annotations.length <= 0)
            {
                continue;
            }
            //获取非自定义校验注解
            List<Annotation> valiAnnotation = CustomVali.getCustomAnnotation(annotations, false);
//            int arg = new Integer(parameter.getName().replace("arg", ""));
            Object paramValue = null;
            try {
                paramValue = objects[arg];
            } catch (Exception e) {
//                System.out.println("Exception ");
            }
            if (!valiAnnotation.isEmpty()) {

                //调用hibernate的校验方式
                validate.throwException(validate.validateParameter(target, method, paramValue, arg));
            } else {
                //判断是否是自定义校验注解
                List<Annotation> valiAnn = CustomVali.getCustomAnnotation(annotations, true);
                for (Annotation annotation : valiAnn) {
                    Class annClazz = annotation.annotationType();

                    Constraint constraint = (Constraint) annClazz.getAnnotation(Constraint.class);
                    Class<? extends ConstraintValidator<Annotation, Object>>[] valis = (Class<? extends ConstraintValidator<Annotation, Object>>[]) constraint.validatedBy();
                    for (Class<? extends ConstraintValidator<Annotation, Object>> vali : valis) {
                        ConstraintValidator<Annotation, Object> constraintValidator = vali.newInstance();
                        constraintValidator.initialize(annotation);
                        //这里因为暂时还未得到校验器ConstraintValidatorContext上下文对象，所以有些功能暂时无法使用
                        boolean valid = constraintValidator.isValid(paramValue, null);
                        if (!valid) {
                            Method msgtMethod = annotation.getClass().getMethod("message");
                            String message = (String) msgtMethod.invoke(annotation);
                            throw new CommonException(-1, message);

                        }


                    }
                }
            }
        }
    }


}